package com.ls.fw.mvc.springmvc.support.interceptor;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.core.NamedThreadLocal;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;

import com.ls.fw.web.core.servlet.utils.UrlUtils;
import com.ls.fw.web.core.support.WebContext;
import com.ls.fw.web.core.support.matcher.IpAddressMatcher;
import com.ls.fw.web.core.support.matcher.RequestMatcher;

public class WebContextInterceptor extends BaseInterceptor {
	  
    private NamedThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<Long>("StopWatch-StartTime");
   
    /**
     * 允许访问的地址（多个用“,”分割）
     */
    private String addrs;
    
    private List<RequestMatcher> list = new ArrayList<RequestMatcher>();
       
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
			Object arg2) throws Exception {
		boolean ok = false;
		if(list==null || list.isEmpty()){
			ok = true;
		}else{
			for (RequestMatcher matcher : list) {
				if(matcher.matches(request)){
					ok = true;
				}
			}
		}
		WebContext.getInstance().setRequest(request);
		WebContext.getInstance().setResponse(response);
		long beginTime = System.currentTimeMillis();//1、开始时间
	    startTimeThreadLocal.set(beginTime);//线程绑定变量（该数据只有当前请求的线程可见）
		return ok;
	}

	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		long endTime = System.currentTimeMillis();//2、结束时间
        long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量（开始时间）
        long consumeTime = endTime - beginTime;//3、消耗的时间
        if (consumeTime > 500)
        {//此处认为处理时间超过500毫秒的请求为慢请求
            //TODO 记录到日志文件
        	logger.warn(String.format("%s 耗时  %d millis", UrlUtils.buildFullRequestUrl(request), consumeTime));
        }else{
          	logger.debug(String.format("%s 耗时  %d millis", UrlUtils.buildFullRequestUrl(request), consumeTime));
        }
	}

	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
			Object handler, ModelAndView mav) throws Exception {
		if(mav!=null && !mav.hasView()){
			 if (handler instanceof HandlerMethod) {
				 HandlerMethod handlerMethod = (HandlerMethod) handler;
				 RequestMapping requestMapping = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), RequestMapping.class);
				 String currentViewPrefix = "";
				 if (requestMapping != null && requestMapping.value().length > 0) {
		            currentViewPrefix += requestMapping.value()[0];
		         }
				 requestMapping = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), RequestMapping.class);
		         if (requestMapping != null && requestMapping.value().length > 0) {
		        	 currentViewPrefix += requestMapping.value()[0];
		         }
				 mav.setViewName(currentViewPrefix);
			 }   
		}
	}

	public String getAddrs() {
		return this.addrs;
	}

	public void setAddrs(String addrs) {
		this.addrs = addrs;
		if (addrs.indexOf(',') > 0) {
			String[] addressAndMasks = StringUtils.split(addrs, ",");
			if(addressAndMasks!=null){
				for (String string : addressAndMasks) {
				    RequestMatcher matcher = new IpAddressMatcher(string);
				    list.add(matcher);
				}
			}
		}
	}

	public List<RequestMatcher> getList() {
		return this.list;
	}

	public void setList(List<RequestMatcher> list) {
		this.list = list;
	}

}
